package com.suray.wcs.service.thread;


import com.suray.basic.wcs.plc.enums.RobotStatus;
import com.suray.basic.wcs.plc.pojo.Robot;
import com.suray.basic.wcs.plc.pojo.RobotHeartBaseResult;
import com.suray.basic.wcs.plc.pojo.TaskReceive;
import com.suray.basic.wcs.plc.utils.StringBeanUtil;
import com.suray.commin.core.utils.StringUtils;
import com.suray.wcs.service.core.util.LongConnSendUtilLora;
import com.suray.wcs.service.rescontact.ResultContainer;
import com.suray.wcs.service.robot.ToRobot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * @author Shaozn
 */
public class RobotHeartThread extends Thread {
    private Robot robot;
    /**
     * 心跳间隔时间
     */
    private static final int INTERVAL_TIME = 500;
    private static Logger log = LoggerFactory.getLogger(RobotHeartThread.class);

    /**
     * 构造方法
     */
    public RobotHeartThread(Robot robot) {
        super(robot.getName() + "心跳线程");
        this.robot = robot;
    }

    @Override
    public void run() {
        while (true) {
            try {
                // 发送心跳
                processResult(ToRobot.getInstance(robot).heartRequest(StringBeanUtil.toString(robot.getRobotHeart())));
            } catch (IOException e) {
                LongConnSendUtilLora.robotSocketMap.remove(robot);
                // 机械臂不是故障状态才设置离线
                if (!RobotStatus.ERROR.equals(robot.getStatus())) {
                    robot.setStatus(RobotStatus.OFF_LINE);
                }
                log.error("{}心跳通讯异常：{}", robot.getName(), e.getMessage(), e);
            } catch (Exception e) {
                LongConnSendUtilLora.robotSocketMap.remove(robot);
                log.error("{}心跳通讯出现故障：{}", robot.getName(), e.getMessage(), e);
            }
            try {
                Thread.sleep(INTERVAL_TIME);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 执行结果
     *
     * @param receiveStr
     */
    public void processResult(String receiveStr) {
        log.info("接收到报文：{}",receiveStr);
        if (StringUtils.isNotEmpty(receiveStr)) {
            try{
                // 格式校验
                if(checkReceiveStr(receiveStr)){
                    long receiveTime = System.currentTimeMillis();
                    RobotHeartBaseResult robotHeartBaseResult = StringBeanUtil.toRobotHeartBaseResult(receiveStr);
                    robotHeartBaseResult.setRetTime(receiveTime);
                    // 设置机械臂状态
                    robot.setStatus(RobotStatus.parseStatus(robotHeartBaseResult.getStatus() == null ? -1 : robotHeartBaseResult.getStatus()));
                    // 如果有货物到位通知，则存放货位到位通知结果
                    if(robotHeartBaseResult.getCargoReadyTaskNo() != null) {
                        ResultContainer.getContainer(robot).putRobotResult(robotHeartBaseResult.getCargoReadyTaskNo(), robotHeartBaseResult);
                    }
                    // 如果有任务下发，则存放任务下发结果
                    if(robotHeartBaseResult.getTaskSendTaskNo() != null) {
                        ResultContainer.getContainer(robot).putRobotResult(robotHeartBaseResult.getTaskSendTaskNo(), robotHeartBaseResult);
                    }
                    // 任务反馈接收后，需要修改任务状态及返回任务反馈接收状态
                    if(robotHeartBaseResult.getWcsTaskNo() != null){
                        TaskReceive taskReceive = new TaskReceive(robotHeartBaseResult.getWcsTaskNo(), 1);
                        robot.getRobotHeart().getTaskReceiveCommand().offer(taskReceive);
                        // TODO 修改任务状态

                        // TODO 码垛/拆垛完成时处理

                    }
                }else {
                    //返回报文格式不正确
                    log.error("报文格式不正确：{}",receiveStr);
                }
            }catch (Exception e){
                log.error("接收报文：{},处理异常：{}",receiveStr, e.getMessage(),e);
            }
        }else {
            // 返回报文为空
            log.error("报文为空");
        }
    }

    private boolean checkReceiveStr(String receiveStr) {
        // 头尾校验
        if(!receiveStr.startsWith(StringBeanUtil.PRE_STR) || !receiveStr.endsWith(StringBeanUtil.SUF_STR)){
            return false;
        }
        // 数据位数校验
        if(receiveStr.split(StringBeanUtil.SPLIT_STR).length != StringBeanUtil.LIMIT_COUNT){
            return false;
        }
        return true;
    }
}
